import fileio from '@ohos.fileio'
import { util } from '@kit.ArkTS';
import Logger from './Logger'
import { BoolObj } from "./recallInterface"
import DateTimeUtil, { sleep } from './DateTimeUtil';
export async function monitor(boolObj: BoolObj): Promise<boolean> {
  return new Promise((resolve) => {
    let interval = setInterval(() => {
      if (boolObj.get() == boolObj.cond) {
        boolObj.set(!boolObj.get())
        clearInterval(interval)
        resolve(boolObj.get())
      }
    }, 4)
  })
}

export function bufferToString(buffer: ArrayBuffer): string {
  let TAG = "_:_btostring"
  let uint8buf = new Uint8Array(buffer)
  let textDecoderOptions: util.TextDecoderOptions = {
    fatal: false,
    ignoreBOM: true
  }
  let decodeWithStreamOptions: util.DecodeWithStreamOptions = {
    stream: false
  }
  let textDecoder = util.TextDecoder.create('utf-8', textDecoderOptions);
  let retStr = textDecoder.decodeWithStream(uint8buf, decodeWithStreamOptions);
  return retStr
}

export function encode(encoding = "utf-8") {
  let textEncoder = new util.TextEncoder(encoding);
}

export class fileManager {
  conv: string = ""
  static dir = ""
  fileName: string = ""

  constructor(dir = "", filename = "/conv1.txt", clear = false) {
    let TAG = "_:fileUtils"
    if (dir == "") {
      dir = fileManager.dir
    }
    if (filename[0]!="/"){
      filename="/"+filename
    }
    this.fileName = filename
    this.conv = dir + filename
    console.log("_:[file] file full name " + this.conv)
    if (dir != "") {
      let fd = fileio.openSync(this.conv, 0o100, 0o660)
      console.log("_:f constructor fd is " + fd)
      fileio.close(fd)
      if (clear) {
        this.clearA()
      }
    } else {
      console.error(TAG, "filename empty")
    }
  }

  readall(replaceBlank = false) {
    let fd = fileio.openSync(this.conv, 0o2)
    let buf = new ArrayBuffer(100000)
    // console.log("_:_f in readall fd is " + fd)
    let len = fileio.readSync(fd, buf)
    let content = bufferToString(buf)
    // console.log("_:_f in readall content=" + content)
    if (!replaceBlank) {
      return content
    } else {
      return content.replace(/\n/g, "").trim()
    }
  }

  async writeA(info, cleanBeforeWrite: boolean,replaceLn:boolean=true) {
    let TAG="_:_writeA"
    console.log(TAG,"entered,content=","["+info+"]",cleanBeforeWrite,replaceLn)
    if (cleanBeforeWrite) {
      await this.clearA()
    }
    if (replaceLn) {
      info = info.replace(/\n/g, "").replace(/\s+/, "")
    }
    let fd = await fileio.open(this.conv, 0o2 | 0o2000, 0o660)
    await fileio.write(fd, info)
    console.log("_:f writeA ", this.fileName, "finish", fd, "length", info.length, info.replace(/\n/g, "").length,
      info.replace(/\n/g, ""))
  }

  async listenA(clearAfterListen: boolean) {
    let TAG = "_:f listenA " + this.fileName
    let content = ""
    console.error(TAG, "listening", content.length, content.replace(/\n/g, "").length,
      "[" + content.replace(/\n/g, "") + "]", "[" + content + "]")
    while (true) {
      content = await this.readA()
      // console.log(TAG, "------ing", "[" + content.replace(/\n/g, "").trim() + "]")
      if (content.replace(/\n/g, "").trim() != "") {
        break
      }
      await sleep(1000)
    }
    console.error(TAG, "listened", content)
    if (clearAfterListen) {
      await this.clearA()
    }
    return content
  }

  async listenA2(clearAfterListen) {
    let TAG = "_:_f listenA " + this.fileName
    let fd = await fileio.open(this.conv, 0o2)
    console.error(TAG, "entered", fd)
    let buf = new ArrayBuffer(100000)
    let content: string = ""
    while (true) {
      let readOut = await fileio.read(fd, buf)
      if (readOut.bytesRead > 0) {
        content = bufferToString(buf);
        break
      }
      await sleep(100)
      console.log(TAG, "listening", readOut.bytesRead, readOut.offset, readOut.buffer, content)
    }
    console.warn(TAG, "listened!", content)
    if (clearAfterListen) {
      await this.clearA()
    }
    return content
  }

  async readA(replaceLn = true,bufsize=5000): Promise<string> {
    let fd = await fileio.open(this.conv, 0o2)
    let buf = new ArrayBuffer(bufsize)
    console.log("_:_f in readA fd is " + fd)
    let readOut = await fileio.read(fd, buf)
    let content = bufferToString(buf)
    console.log("_:_f in readA content=" + content)
    if (replaceLn) {
      return content.replace(/\n/g, "").trim()
    }
    return content.trim()
  }

  readlist() :string[]{
    let TAG = "_:_readList"
    let fd = fileio.openSync(this.conv, 0o2)
    let buf = new ArrayBuffer(100000)
    fileio.readSync(fd, buf)
    let content = bufferToString(buf)
    let listcontent = content.split("<split>")
    if (listcontent.length <= 1 && listcontent[0] == "") {
      return []
    } else {
      listcontent = listcontent.slice(0, listcontent.length - 1)
      return listcontent
    }
  }

  write(conv, type, modify = true, addSplit = true):void { //self:0 bot:1
    let fd = fileio.openSync(this.conv, 0o2 | 0o2000, 0o660)
    let listcontent = this.readlist()
    if (modify) {
      if (listcontent.length % 2 != type) {
        fileio.writeSync(fd, "好的·" + "<split>")
      }
    }
    if (addSplit) {
      fileio.writeSync(fd, conv + "<split>")
    } else {
      fileio.writeSync(fd, conv)
    }
    console.log("_:f write finish", fd, conv, type, "modify=", modify, "addSplit=", addSplit)
  }

  pop():void {
    let TAG = "_:_filePop"
    let listcontent = this.readlist()
    console.log(TAG, "origin", JSON.stringify(listcontent))
    let fd = fileio.openSync(this.conv, 0o2 | 0o1000, 0o660)
    for (let i = 0; i < listcontent.length - 1; i++) {
      console.log(TAG, "processing", listcontent[i])
      fileio.writeSync(fd, listcontent[i] + "<split>")
    }
    listcontent = this.readlist()
    console.log(TAG, "now", JSON.stringify(listcontent))
  }

  print():void {
    let filelist = this.readlist()
    let TAG = "_:_[FM]"
    console.log(TAG, "___________start__________")
    let cnt = 0
    for (let item of filelist) {
      console.log(TAG, String(cnt++), item)
    }
    console.log(TAG, "___________stop___________")
  }

  clear():void {
    fileio.unlinkSync(this.conv)
    let fd = fileio.openSync(this.conv, 0o100, 0o660)
    console.error("_:f cleared", fd)
    fileio.close(fd)
  }

  async clearA(): Promise<void> {
    fileio.unlinkSync(this.conv)
    let fd = await fileio.open(this.conv, 0o100, 0o660)
    console.error("_:f cleared", fd)
    fileio.close(fd)
  }

  gettask() :string{
    let fd = fileio.openSync(this.conv, 0o2)
    let buf = new ArrayBuffer(100000)
    fileio.readSync(fd, buf)
    let content = bufferToString(buf)
    let listcontent = content.split("<split>")
    listcontent = listcontent.slice(0, listcontent.length - 1)
    listcontent = listcontent.reverse()
    for (let item of listcontent) {
      if (item.includes("执行任务")
        || item.includes("execute task")
        || item.includes("学习任务")
        || item.includes("learn task")) {
        return item
      }
    }
    return "新建联系人，姓名geyiheng，手机号13681976370，保存退出"
  }

  getHistory(task):string {
    let listcontent = this.readlist()
    let history = "你需要分析任务自动执行的效果，刚才的任务是" + task + ""
    listcontent.map((content, index) => {
      if (index % 2 == 1) {
        history += "=>" + content
      }
    })
    console.log("_:_getHistory", history.replace(/\n/g, ""))
    return history
  }

  getMode():number {
    let TAG = "_:_[currentMode]"
    console.log(TAG, "entered")
    let fd = fileio.openSync(this.conv, 0o2)
    let buf = new ArrayBuffer(100000)
    fileio.readSync(fd, buf)
    let content = bufferToString(buf)
    let listcontent = content.split("<split>")
    listcontent = listcontent.slice(0, listcontent.length - 1)
    listcontent = listcontent.reverse()
    console.log(TAG, JSON.stringify(listcontent))
    let cntE = 0
    for (let item of listcontent) {
      if (item.includes("执行任务") || item.includes("execute task")) {
        break
      }
      cntE++
    }
    let cntL = 0
    for (let item of listcontent) {
      if (item.includes("学习任务") || item.includes("learn task")) {
        break
      }
      cntL++
    }
    console.log(TAG, cntL, cntE)
    if (cntL > cntE) {
      return 1
    } else if (cntE > cntL) {
      return -1
    }
    console.log(TAG, "not defined")
    return 0
  }
}
